home *** CD-ROM | disk | FTP | other *** search
- RTTI (Run-time Type information for C++)
- ------------------------------------------
- Author - Arindam Banerji (axb@cse.nd.edu)
- 384 FitzPatrick Hall
- Dept. of Computer Science & Engineering
- University of Notre Dame
- Notre Dame, IN 46556
-
- Please report any problems to axb@cse.nd.edu. I make no guarantees about
- this software.
-
- This directory contains the sources and appropriate binaries for an
- extensible C++ run-time type system. This system is loosely based on the
- RTTI system demonstrated by Stousroup in "The C++ Programming Language".
-
- The files in this directory are
-
- rtti.README - this file
-
- rtti_make_vars - File containing the defintiions of some of the make
- make file variables used in building the rtti libraries.
-
- The file in the include directory are
- String.h - description of a simple String class. The name of the class is
- "string". In case, this conflicts with any of the other class
- names that you are using, then enclose the class declaration
- within something like
- #define string __xx_string
- #undef string
-
- trace.h - a simple trace class that helps in debugging. The name of the
- class is "trace". In case, this conflicts with any other class
- names that you are using, then enclose the class declaration
- within something like
- #define trace __xx_trace
- #undef trace
-
-
- rtti_entry.h - The main include file for the rtti classes. This file pulls
- in the other include files (hence, this is the file that
- user code pulls in). In addition, it defines the classes
- that allow for the rtti implmentation to be bootstrapped.
-
- rtti.h - This file declares the class definitions for the rtti type
- system (ie: all the classes that are actually visible to the
- user are declared here).
-
- rttiimpl.h - This file declares some of the classes used to implment the
- manipulation and maintenance of base class lists, in the rtti
- type system.
-
- rttimacros.h - Most users will just use this for building the rtti
- scaffoldings into their class declarations and defitions.
- The assumption here is that the declarations and definitions
- are in two separate files ie: for a class such as foo, there
- are two files foo.c and foo.h. Obviously, each file may
- contain more than one class declaration and definition (foo.c
- and foo.h may define and declare the classes foo, bar, Lists,
- etc.)
-
-
- The files in the src directory are
- String.c - A simple string class definition. The name of this class
- is string. In case, this name conflicts with other classes
- that you are using, then enclose the member functions
- within something like
- #define string __xx_string
- #undef string
-
-
- trace.c - Member function definitions for the trace class. The name of the
- class is "trace". In case, this conflicts with any other class
- names that you are using, then enclose the class declaration
- within something like
- #define trace __xx_trace
- #undef trace
-
- rtti_entry.c - This file contains the defintion of the hndl_recusrsion class
- that allows the type system to be bootstrapped.
-
-
- rtti.c - This file contains the implmentation of the rtti classes.
-
- Implementation Notes :
- ----------------------
-
- All classes in this RTTI system inherit from the CLASS base class. This
- allows public virtual inheritance to work. CLASS has very little
- functionality associated with it, although it itself has the RTTI
- scaffoldings neccessary for all users of RTTI. The narrowing facility
- (ie: going from a base class pointer to a derived class pointer) depends
- upon the use of CLASS.
-
- The Type_info class is the core of the RTTI implementation. It is
- initialized once, per class. The constructors accept a list of the base
- classes and the name of the class. The typeid class provides an interface
- to the RTTI system and users get at the RTTI thru this class. This class
- just acts like a pass thru for the Type_info class.
-
- The base_iterator class is initialized with the list of base classes. It
- allows the clients of the Type_info class to iterate thru the list of bases.
-
- The other classes such as trace and string are fairly trivial.
-
- Usage :
- --------
-
- Every class that uses the RTTI must use some scaffolding in both the
- declaration and the definition of the class. The declaration must
- contain the following:
-
- For every RTTI class, a static Type_info class needs to be created, as in
- static const Type_info info_obj ;
-
- For every RTTI class, two functions must be created to retrieve the Type
- information (one a virtual function and another a simple function), as in
- virtual typeid get_info() const ;
- static typeid info() ;
-
- In order to allow a base class pointer to be converted into its appropriate
- derived class pointer, the narrowing facility is provided.
- static Type_info *_narrow(CLASS *) ;
-
- In order for the narrowing facility to work in the presence of virtual
- public inheritance, every RTTI class defines a virtual function that
- returns its this pointer.
- virtual void *get_this_ptr(void) const ;
-
-
- However, the macros defined in rttimacros.h make it almost trivial to
- add support for this in the class declarations. The user has to add just
- a simple line that automatically generates all the above-mentioned
- declarations.
-
- Example 1
- Consider a class foo, of the form
- class foo : public virtual CLASS
- {
- public :
- foo() ;
- ~foo() ;
- .....
- } ;
-
- In order to create scaffolding for this, add the following line to the
- class declaration (ie: in the .h file) as in :
- class foo : public virtual CLASS
- {
- public :
- foo() ;
- ~foo() ;
- RTTI_SCAFFOLDING_DECL(foo)
- .....
- } ; // some further additions need to be made in the .c file, too
-
- Example 2
- If instead of the simplistic foo, we had
- template <class T>
- class foo1 : public LinkedList<T> { ...
-
- add the following line
- RTTI_SCAFFOLDING_DECL_TEMPL(foo1)
-
- Example 3
- In case things are a little more complicated, as in
- template <class T, int n >
- class foo2 { ...
-
- add the following line
- RTTI_SCAFFOLDING_DECL_TEMPL_2(foo2,T,n)
-
- Example 4
- For the following
- template <class T, int n, class Z >
- class foo3 : public some_parent<T,n> { ...
- add the following line
- RTTI_SCAFFOLDING_DECL_TEMPL_3(foo3,T,n,Z)
-
-
- The class definition in the .c or .C files must include a corresponding
- piece of scaffolding. The scaffolding is as follows :
-
- The set of direct bases for a particular RTTI class need to be listed and
- passed as a parameter to the Type_info object for the class. For a class
- called TYPE with just one parent class (say PARENT1), the following could
- be used.
- static const Type_info* TYPE_set_bases[] =
- {(const Type_info *) &PARENT1::info_obj, 0 } ;
-
- The Type_info object for the class Type mentioned above needs to be
- instantiated. One parameter is the name TYPE and the other is the list of
- base classes declared above.
- const Type_info TYPE::info_obj("TYPE", TYPE_set_bases) ;
-
- The two functions that allow for the retrival of the Type_info classes
- from the RTTI class need to be defined (as show below).
- typeid TYPE::get_info() const { return &info_obj; }
- typeid TYPE::info() { return &info_obj; }
-
- The narrowing mechanism, is an extremely useful part of the RTTI interface.
- Often base class pointers to derived class objects are much easier to pass
- around (especially where a strict separation between interface and
- implementation is desired.) However, during the actual use of such a pointer
- it is necessary to retrieve the actual derived object type. Thus, a combina-
- -tion of the Type information of the object and the narrowing mechanism
- may be used to get back the original pointer. The following two functions
- allow for this to happen.
- TYPE *TYPE::_narrow(CLASS *obj)
- {
- void *ret = NULL ;
- if ( ptr_cast(TYPE,obj))
- ret = obj->get_this_ptr() ;
- return ( (TYPE *) ret) ;
- }
-
- void *TYPE::get_this_ptr(void) const
- {
- return ((void *) this);
- }
-
-
- Again, the macros defined in rttimacros.h make it almost trivial to
- add support for this in the class definitions. The user has to add just
- a simple line that automatically generates all the above-mentioned
- member functions and data declarations.
-
- Example 1
- For a class foo, of the form
- class foo : public virtual CLASS
- {
- public :
- foo() ;
- ~foo() ;
- RTTI_SCAFFOLDING_DECL(foo)
- .....
- } ;
-
- In order to create scaffolding for this, add the following line to the
- class definition (ie: in the .c file) as in :
- RTTI_SCAFFOLDING_IMPL1(foo, CLASS)
-
- Similiarly, if the class foo had no parents use the macro
- RTTI_SCAFFOLDING_IMPL0(foo)
- and if it had two parents, use the macro
- RTTI_SCAFFOLDING_IMPL2(foo,CLASS,PARENT2)
- and so on.
-
- Example 2
- If instead of the simplistic foo, we had
- template <class T>
- class foo1 { ...
-
- add the following line to the definition file
- TEMPL_RTTI_IMPL_SCAFF_0_1(foo1,foo1<T>,class T)
- If foo1 instead had the parameters <classT, int n> we could use
- TEMPL_RTTI_IMPL_SCAFF_0_2(foo1,class T,int n,T,n)
- and so on.
-
- Example 3
- For the following
- template <class T, int n, class Z >
- class foo3 : public some_parent<T,n> { ...
- add the following line
- TEMPL_RTTI_IMPL_SCAFF_1_3(foo3,class T,int n,class Z,some_parent<T,n>,T,n,Z)
-
- As you might have noticed the the format of the macro name is
- TEMPL_RTTI_IMPL_SCAFF_numparents_numparms (Please see rttimacros.h )
-
- User interface
- ---------------
- 1.
- The user may retieve the static type information of an object thru the
- the following macro
- static_type_info(T)
- where T is the Type name.
-
- 2.
- To retrieve the Type information for a given pointer , use
- ptr_type_info(p)
- where p is the appropriate pointer.
-
- 3.
- To retrieve the Type information for a given reference , use
- ref_type_info(r)
- where p is the appropriate reference.
-
- 4.
- To check whether a pointer may be cast to particular type, use any of the
- following macros (returns NULL, is invalid)
- ptr_cast(T,p) , where T is the Type and p the pointer.
- as in
- template <class T>
- class foo : public virtual CLASS
- use the expression
- ptr_cast(Type_to_be_cast_to, ptr_to_foo_object)
-
- Similiarly, to compare a pointer p with the following
- template <class T, int n , class Z>
- class foo2 : public some_parent<T,n, Z>
- use
- ptr_cast_3(foo2,T,n,Z,p)
-
-
- 5.
- To narrow a pointer p to a base foo2 (as shown in 4. above)
- use foo2<T,n,Z>::_narrow(p)
-
-
-
- Building
- ---------
- The Makefile shown in bin pulls in the include file rtti_make_vars. This
- file contains the defition of the variables that'll most probably need to
- changed, during the compilation such as path name of the C++ compiler, etc.
-
- I have used xlC and cfront 3.0.1 (on the RS/6000s) to build these sources
- and have not had any problems. Since, template implmentations on different
- compilers are quite different, you might need to tweak the macros somewhat
- to make your compiler happy.
-